#include "..\os\kernel.h"
#include "..\common\led.h"
#include "..\common\util.h"


/**
 * \file main.c
 * \author Clecio Varjao and Leanne Ross
 * \date October 2007
 * \brief Application sample using the RTOS implementation
 *
 * \p This Application executes 4 PERIODIC tasks, 1 SYSTEM Task and 1 RR task.
 * \p The PERIODIC tasks executes a 'ping-pong' using the LED_D5_GREEN for the Ping() and LED_D5_RED for Pong().
 * \p The Ping() and Pong() have two steps: turn led on, and turn led off.
 * \p There is an implementation of an EVENT using a RR task to increment a number ( Producer() ), and a SYSTEM task to 'read' the buffer when it reachs an specified number.
 */

const unsigned char PPP[]= {1, 5, 2, 5, 3, 5, 4, 5};
const unsigned int PT=4;

/*!
 Ping Task
 */
void Ping() 
{
  for(;;){
  	if (Task_GetArg()==0){
		enable_led(LED_D5_GREEN);
	}else{
		disable_led(LED_D5_GREEN);
	}
    Task_Next();
  }
}

/*!
 Pong Task
 */
void Pong() 
{
  for(;;) {
  	if (Task_GetArg()==0){
		enable_led(LED_D5_RED);
	} else {
		disable_led(LED_D5_RED);
	}
    Task_Next();
	
  }
}

volatile static EVENT *fullBuffer; //!< Event used to coordinate the Consumer and Producer tasks
volatile unsigned int Ptop=100;
volatile unsigned int Ctop=150;

/*!
 Consumer Task
 */
void Consumer(){
	while(1){
		Event_Wait((EVENT*)fullBuffer);	// change the State to WAITING	
		Task_Next();
		enable_led(LED_D2_GREEN);
	}
}

/*!
 Producer Task
 */
void Producer(){
	volatile static unsigned int buffer=0;
	while (1){		
		buffer++;
		if (buffer<Ptop){
			enable_led(LED_D2_RED);
		} else if (buffer==Ptop){
			disable_led(LED_D2_RED);		
			Event_Signal((EVENT*)fullBuffer);
		} else if (buffer>=Ctop){
			disable_led(LED_D2_GREEN);
			buffer=0;
		}
		Task_Next();
	}
}

/*!
 * \brief Main task.
 *
 * This is a SYSTEM task create by the RTOS. This will be the first task executed.
 */
int main() 
{
	init_leds();
	fullBuffer=Event_Init();

	blink_led_for(LED_D2|LED_D5, 1000);
	delay(1000);
	blink_led_for(LED_D2|LED_D5, 1000);
	delay(1000);
	blink_led_for(LED_D2|LED_D5, 1000);
	delay(200);
	blink_led_for(LED_D2|LED_D5, 1000);

	Task_Create(Ping, 0, PERIODIC, 1);
	Task_Create(Ping, 1, PERIODIC, 2);
	Task_Create(Pong, 0, PERIODIC, 3);	
	Task_Create(Pong, 1, PERIODIC, 4);

	Task_Create(Producer, 3, RR, 'E');
	Task_Create(Consumer, 4, SYSTEM, 'F');
      
   return 1;
}
